package com.tyk.bookstore.front.product.service.impl;


import com.tyk.bookstore.front.common.cache.anno.ICache;
import com.tyk.bookstore.front.common.cache.constant.CacheConstant;
import com.tyk.bookstore.front.common.core.util.TreeUtil;
import com.tyk.bookstore.front.product.model.dto.ClazzNestDto;
import com.tyk.bookstore.front.product.model.vo.ClazzNestVo;
import com.tyk.bookstore.front.product.repository.ClassificationRepository;
import com.tyk.bookstore.front.product.service.ClassificationService;
import com.tyk.bookstore.front.product.util.MapStructProduct;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;


/**
 * @author tyk
 * @description 分类管理
 */
@Service
@RequiredArgsConstructor
public class ClassificationServiceImp implements ClassificationService {
    private final ClassificationRepository classificationRepository;
    private final MapStructProduct mapStructProduct;

    @Override
    @ICache(
            prefix = CacheConstant.PRODUCT_CLAZZ_PREFIX,
            expireTime = CacheConstant.PRODUCT_CLAZZ_EXPIRE_TIME,
            lockPrefix = CacheConstant.PRODUCT_CLAZZ_LOCK_PREFIX
    )
    public List<ClazzNestVo> getNestList() {
        // 查询所有分类
        List<ClazzNestDto> dtoList = classificationRepository.selectClazzNestDtoList();
        // 构建分类树并返回
        return TreeUtil.buildTree(
                dtoList,
                ClazzNestDto::getId,
                ClazzNestDto::getParentId,
                mapStructProduct::toClazzNestVo,
                ClazzNestVo::addChild
        );
    }

    /**
     * 构建分类树
     *
     * @param dtoList 原始结点列表
     * @param dtoMap  原始结点列表：以parentId为key进行分组
     * @return 分类树
     * 调用：buildNestVoList(dtoMap, dtoMap.get(0L))
     */
    private List<ClazzNestVo> buildNestVoList(List<ClazzNestDto> dtoList, Map<Long, List<ClazzNestDto>> dtoMap) {
        return dtoList.stream().map(d -> {
            ClazzNestVo v = mapStructProduct.toClassificationNestVo(d);
            if (dtoMap.containsKey(v.getId())) {
                v.setChildren(buildNestVoList(dtoMap.get(v.getId()), dtoMap));
            }
            return v;
        }).toList();
    }
}
